import Layouts from '@/components/Layout';
import { getMessageBasicInfo, getUserInfo } from '@/service/api/user';
import { MessageDetail, UserInfo } from '@/types/user';
import { CommentOutlined } from '@ant-design/icons';
import { Avatar, Button, Card, Input, message, PageHeader } from 'antd';
import configs from '../../../../config/env';
import React, { useEffect, useRef, useState } from 'react';
import { useParams, history, useSelector, useLocation } from 'umi';
import './index.less';
import { PubSub } from 'pubsub-js';
import { createWebSocket, closeWebSocket, websocket } from './websocket';
import { Element, scroller } from 'react-scroll';
import dayjs from 'dayjs';
const MsgDetail: React.FC = () => {
  let messageSocket: null = null;
  let arr2 = [];
  const loaction = useLocation();
  const params: { id: string } = useParams();
  // 用户信息
  const userInfo = useSelector(
    (state: { userInfoModel: { userInfo: UserInfo } }) => state.userInfoModel.userInfo,
  );
  const messagesEnd = useRef<HTMLDivElement>(null);
  const [loading, setLoading] = useState<boolean>(false);
  let [basicInfo, setBasicInfo] = useState<any[]>([]);
  const [reqUserInfo, setReqUserInfo] = useState<UserInfo>();
  const [text, setText] = useState<string>('');
  const getMessageDetailInfoData = async () => {
    const { data }: { data: any[] } = await getMessageBasicInfo({
      sendUserId: Number(params.id),
    });
    setBasicInfo(data);
    sessionStorage.setItem(
      'msg',
      JSON.stringify(
        data.map((item) => ({
          sendUserId: Number(item.sendUser.userId),
          createTime: item.createTime,
          sendUser: {
            avatar: item.sendUser.avatar,
          },
          content: item.content,
        })),
      ),
    );
    onMessageScroll('bottomElement', 'chatItems');
    messageSocket = PubSub.subscribe('message', function (topic, message) {
      //message 为接收到的消息  这里进行业务处理
      // console.log('ws获取：', message);
      if (message.type === 0) {
      } else {
        arr2.push({
          sendUserId: Number(message.sendUser.userId),
          createTime: message.createTime,
          sendUser: {
            avatar: message.sendUser.avatar,
          },
          content: message.message,
        });
        // console.log(
        //   uniqueFromObject([...JSON.parse(sessionStorage.getItem('msg') as string), ...arr2]),
        // );
        setBasicInfo(
          uniqueFromObject([...JSON.parse(sessionStorage.getItem('msg') as string), ...arr2]),
        );
        onMessageScroll('bottomElement', 'chatItems');
      }
    });
  };
  const handleChange = (e: { target: { value: React.SetStateAction<string> } }) => {
    setText(e.target.value);
  };
  const getUserInfoData = async () => {
    if (localStorage.getItem('token')) {
      const { data }: { data: UserInfo } = await getUserInfo();
      createWebSocket(
        `ws://114.132.240.29:3000/websocket/message/${data.userId}/${Number(params.id)}`,
      );
      setReqUserInfo(data);
    }
  };
  function generatorPrimaryKey(object: any) {
    // 如果有缓存，则直接返回
    if (object.__primary__) {
      return object.__primary__;
    }
    const keys = Object.keys(object);
    let primaryKey = '';
    for (const key of keys) {
      primaryKey += object[key] + '&';
    }
    // 缓存本次key的生成结果
    object.__primary__ = primaryKey;
    return primaryKey;
  }
  // 深度去重
  function uniqueFromObject(array: any[]): any[] {
    let object = {},
      resultList = [],
      primaryKey;
    array.forEach((item, index) => {
      primaryKey = generatorPrimaryKey(item);
      object[primaryKey] = index;
    });
    for (let key in object) {
      resultList.push(array[object[key]]);
    }
    return resultList;
  }
  const sendMsg = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
    const { code }: { code: string } = e;
    if (code === 'Enter') {
      e.preventDefault(); //禁止回车的默认换行e
      if (text === '') {
        return message.warning('请不要输入空的消息');
      }
      if (!loading) {
        if (websocket) {
          websocket.send(
            JSON.stringify({
              msg: text,
              type: 1,
            }),
          );
          setText('');
          console.log('ws发送');
          basicInfo.push({
            sendUserId: reqUserInfo?.userId,
            createTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
            sendUser: {
              avatar: reqUserInfo?.avatar,
            },
            content: text,
          });
          // console.log(basicInfo);
          sessionStorage.setItem('msg', JSON.stringify(basicInfo));
          setTimeout(() => {
            onMessageScroll('bottomElement', 'chatItems');
          }, 0);
          setLoading(true);
          setTimeout(() => {
            setLoading(false);
          }, 1000);
        }
      } else {
        message.warning('请间隔1秒后发送消息');
      }
    }
  };
  const onMessageScroll = (scrollId: string, containerId: string) => {
    if (messagesEnd.current && messagesEnd) {
      scroller.scrollTo(scrollId, {
        duration: 2000,
        delay: 0,
        smooth: true,
        containerId: containerId,
        offset: messagesEnd.current.scrollTop,
      });
    }
  };
  // useEffect(()=>{
  //   getMessageDetailInfoData
  // },[basicInfo])
  useEffect(() => {
    // 如果详情id不能转成数字的话就证明是用户在路径随便输入的字符串
    if (!isNaN(Number(params.id))) {
      getMessageDetailInfoData();
      getUserInfoData();
    } else {
      history.push('/404');
    }
    //在组件卸载的时候，关闭连接
    return () => {
      PubSub.unsubscribe(messageSocket);
      sessionStorage.removeItem('msg');
      sessionStorage.removeItem('sendMsg');
      sessionStorage.removeItem('receMsg');
      closeWebSocket();
    };
  }, []);
  const title = (
    <div className="card_tit_wrap">
      <div className="ico">
        <CommentOutlined />
      </div>
      <span className="card_tit">
        与<span className="u_name">{loaction['query'].nickName}</span>的对话
      </span>
    </div>
  );
  return (
    <Layouts>
      <Button loading={loading} style={{ display: 'none' }}></Button>
      <div>
        <PageHeader
          className="site-page-header"
          onBack={() => {
            history.go(-1);
          }}
          title="返回"
        />
        <Card title={title}>
          <div className="msg_content" ref={messagesEnd} id="chatItems">
            {basicInfo.map((item, index) => {
              return item.sendUserId === userInfo.userId ? (
                <div className="chat_msg send" key={index}>
                  <div className="time">
                    {index !== 0 &&
                      Date.parse(item.createTime) >
                        Date.parse(basicInfo[index - 1].createTime) + 3 * 60 * 1000 &&
                      item.createTime}
                  </div>
                  <div className="chat_message">
                    <div className="author">
                      <Avatar
                        shape="square"
                        size={50}
                        src={
                          item.sendUser.avatar
                            ? configs[process.env.API_ENV as any].API_SERVER + item.sendUser.avatar
                            : '/images/act.e69c9c17.jpg'
                        }
                      />
                    </div>
                    <div className="msg">{item.content}</div>
                  </div>
                </div>
              ) : (
                item.sendUserId === Number(params.id) && (
                  <div className="chat_msg receive" key={index}>
                    <div className="time">
                      {index !== 0 &&
                        Date.parse(item.createTime) >
                          Date.parse(basicInfo[index - 1].createTime) + 3 * 60 * 1000 &&
                        item.createTime}
                    </div>
                    <div className="chat_message">
                      <div className="author">
                        <Avatar
                          shape="square"
                          size={50}
                          src={
                            item.sendUser.avatar
                              ? configs[process.env.API_ENV as any].API_SERVER +
                                item.sendUser.avatar
                              : '/images/act.e69c9c17.jpg'
                          }
                        />
                      </div>
                      <div className="msg">{item.content}</div>
                    </div>
                  </div>
                )
              );
            })}
            <Element name="bottomElement"></Element>
          </div>
          <div className="msg_edit_block">
            <Input.TextArea
              value={text}
              onChange={handleChange}
              rows={4}
              placeholder="按“Enter”键发送"
              onKeyDown={(e) => {
                sendMsg(e);
              }}
            />
          </div>
        </Card>
      </div>
    </Layouts>
  );
};
export default MsgDetail;
